package nl.infodation.emr.pricingservice.ui;

import java.util.Locale;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

import nl.infodation.emr.pricingservice.controller.Connector;
import nl.infodation.emr.pricingservice.controller.ControllerFactory;
import nl.infodation.emr.pricingservice.entity.LanguageSystem;
import nl.infodation.emr.pricingservice.entity.User;
import nl.infodation.emr.pricingservice.security.login.LoginController;
import nl.infodation.emr.pricingservice.ui.component.AbstractBasePanel;
import nl.infodation.emr.pricingservice.ui.page.PricingServiceApplication;
import nl.infodation.emr.pricingservice.ui.page.SessionData;
import nl.infodation.emr.utility.Constants;
import nl.infodation.emr.utility.DateTimeUtil;
import nl.infodation.emr.utility.I18NPricingLangSupport;
import nl.infodation.emr.utility.StringUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.peholmst.i18n4vaadin.I18N;
import com.google.gwt.event.dom.client.KeyCodes;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.terminal.gwt.server.WebApplicationContext;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.CustomLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.NativeButton;
import com.vaadin.ui.PasswordField;
import com.vaadin.ui.Select;
import com.vaadin.ui.TextField;

public class LoginView extends AbstractBasePanel implements ClickListener {
	private static final long serialVersionUID = 1L;
	private static final Logger LOG = LoggerFactory
			.getLogger(LoginView.class);
	
	private final CustomLayout loginLayout = new CustomLayout("login");
	private Label lblTitle = new Label("");
	private final TextField txtUsername = new TextField();
	private final PasswordField txtPassword = new PasswordField();
	private final Button btnLogin = new NativeButton();
	private Label lblVersion;
	
	private final Select selectBox = I18NPricingLangSupport.getSelectBox();
	
	public LoginView(){
		super();
		initialize();
	}
	
	@Override
	public void initLayout() {
		addListener();
		String version = getVersionAndSaveOnSessionData();
		btnLogin.setClickShortcut(KeyCodes.KEY_ENTER, null);
		selectBox.setValue(selectBox.getItemIds().iterator().next());
		selectBox.setWidth("8em");
		txtUsername.focus();
		
		lblVersion = new Label();
		if (!StringUtil.isCodeVersion(version)){
			/*lblVersion.setValue(this.getI18N().getMessage(
					Constants.VERSION_DATABASE));*/
			lblVersion.setStyleName("show-error");
			loginLayout.addComponent(lblVersion, "lblVersion");
		} 
		
		lblTitle.setStyleName("white");
		txtUsername.setStyleName("field");
		txtUsername.focus();
		txtPassword.setStyleName("field");
		selectBox.setStyleName("select_login");
		btnLogin.setStyleName("button_style");
		
		
		loginLayout.addComponent(lblTitle, "title_login");
		loginLayout.addComponent(txtUsername, "username");
		loginLayout.addComponent(txtPassword, "password");
		loginLayout.addComponent(selectBox, "select_login");
		loginLayout.addComponent(btnLogin, "login_button");
		
		this.setContent(loginLayout);
		
		setCaptionForMultiLanguage();
		setDebugIdForMultiLanguage();		
	}
	
	private String getVersionAndSaveOnSessionData() {
		String version = "";
		EntityManager entityManager = null;
		try {
			final EntityManagerFactory EM_FACTORY = Persistence.createEntityManagerFactory(Constants.PRICING_PERSISTENCE_UNIT);
	    	entityManager = EM_FACTORY.createEntityManager();
	    	Connector connector = new Connector();
	    	version = connector.getConfig(Constants.VERSION_KEY, entityManager);
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}
		
		SessionData.setVersion(version);
		return version;
	}
	
	
	private void setCaptionForMultiLanguage() {
		lblTitle.setCaption(this.getI18N().getMessage(Constants.LOGIN_PANEL) + " " + Constants.VERSION_CODE);
		txtUsername.setCaption(this.getI18N().getMessage(Constants.USERNAME_LABEL));
		txtPassword.setCaption(this.getI18N().getMessage(Constants.PASSWORD_LABEL));
		btnLogin.setCaption(this.getI18N().getMessage(Constants.LOGIN_BUTTON));
		btnLogin.setCaption(this.getI18N().getMessage(Constants.LOGIN_BUTTON));
		lblVersion.setCaption(this.getI18N().getMessage(
				Constants.VERSION_DATABASE));
	}
	
	private void addListener() {
		btnLogin.addListener(this);
		
		selectBox.addListener(new Property.ValueChangeListener() {
			private static final long serialVersionUID = 1L;
			
			@Override
			public void valueChange(final ValueChangeEvent event) {
				LanguageSystem language = (LanguageSystem) ControllerFactory.getLanguageSystemController().getObjectById((Integer)selectBox.getValue());
				Locale[] locates = Locale.getAvailableLocales();
				for (Locale locate : locates) {
					if(locate.getLanguage().equals(language.getLanguageSystemCode())){
						switchLocale(locate);
						break;
					}
				}	
			}
		});
	}
	
	private void setDebugIdForMultiLanguage() {
		lblTitle.setDebugId(Constants.LOGIN_PANEL);
		txtUsername.setDebugId(Constants.USERNAME_LABEL);
		txtPassword.setDebugId(Constants.PASSWORD_LABEL);
		btnLogin.setDebugId(Constants.LOGIN_BUTTON);
		lblVersion.setDebugId(Constants.VERSION_DATABASE);
	}
	
	public void buttonClick(final ClickEvent event) {
		final Button source = event.getButton();
		
		if (source.equals(btnLogin)) {
			LOG.info(DateTimeUtil.getNow() + "User logining");
			final LoginController login = new LoginController();
			final User userProfile = login.checkLogin(txtUsername, txtPassword, this.getI18N());
			
			if(userProfile != null && !StringUtil.isEmptyOrBlank(userProfile.getUsername())) {
				// add user to session
				PricingServiceApplication.addUser(userProfile);
				// set current user log-ining
				((WebApplicationContext)this.getApplication().getContext())
					.getHttpSession().setAttribute(Constants.CURRENT_USER_SESSION, userProfile.getUsername());
				// set attribute in session 
				SessionData.setI18N(this.getI18N());
				SessionData.setEnvironment(Constants.UAT_ENVIROMENT);
				SessionData.setCountriesToSee(userProfile.getCountries());
				SessionData.setSuperAdmin(userProfile.isSuperAdmin());
				SessionData.setNormalAdmin(userProfile.isNormalAdmin());
				SessionData.setUsername(userProfile.getUsername());				
				SessionData.setLanguage((Integer)selectBox.getValue());								
				if (userProfile.isSuperAdmin()) {
					SessionData.setDeploymentRoleName(getDeploymentRoleForAdmin());
				} else {
					SessionData.setRoleName(userProfile.getRole().getRoleName());
					SessionData.setRoleId(userProfile.getRole().getRoleId());
				}
				// add username to mark and map to the session
				MainView mainView = new MainView(userProfile.getUsername());
				
				LOG.info(DateTimeUtil.getNow() + "Login successfully");
				((PricingServiceApplication)getApplication()).setContent(mainView);
			}
		}
	}

	private String getDeploymentRoleForAdmin(){
		String deploybus="Afm";
		final EntityManagerFactory EM_FACTORY = Persistence
				.createEntityManagerFactory(Constants.PRICING_PERSISTENCE_UNIT);
		EntityManager entityManager = null;
		try {
			entityManager = EM_FACTORY.createEntityManager();

			Connector connector = new Connector();
				deploybus = connector.getConfig(Constants.DEPLOYMENT_BUSINESS,
						entityManager);

			
		} finally {
			if (entityManager != null && entityManager.isOpen()) {
				entityManager.close();
			}
		}
		return deploybus;
	}


	@Override
	public void reload() {
	}

	@Override
	public void setI18N(I18N i18n) {
	}
}
